﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace GameLogic
{
	public class Unit : PosicionableObject, IRepresentable, ITimeDependant
	{
		public const String Idle1 = "idle1";
		public const String Idle2 = "idle2";
		public const String Walking = "Walking";
		public const String Attack = "Attack";
		public const String Death = "Death";

		protected float trainTime;

		protected float velocity;
		protected int orientation = Unit.Down;
		protected String state = "idle1";
		protected float stateTimeElapsed = 0;

		protected Position2D endPos;

		public Unit()
		{
			
		}

		public virtual string getRepresentationURI()
		{
			return "";
		}

		public float getTrainTime()
		{
			return trainTime;
		}

		override public void setPosition(Position2D pos)
		{
			this.endPos = this.pos = pos;
		}

		public void moveTo(float x, float y)
		{
			endPos = new Position2D(x, y);
		}

		public int getOrientation()
		{
			return orientation;
		}

		public string getRepresentationState()
		{
			return state;
		}

		public float getTimeElapsed()
		{
			return stateTimeElapsed;
		}

		public void update()
		{
			if (pos == endPos) {
				stateTimeElapsed += 0.01F;	// Speed of the non-moving animation
				return;
			} 

			stateTimeElapsed += 0.015F*velocity;	// The speed of the animation depends on the moving speed.
			setState(Unit.Walking);

			Position2D moveVector = new Position2D(endPos.X - pos.X, (endPos.Y - pos.Y)); 

			moveVector.rectificate();
			moveVector.multiplyBy(velocity);

			moveVector.Y = moveVector.Y * 0.71F; // 0.71 because of the perspective

			if (Math.Abs(moveVector.X) + 0.5F >= Math.Abs(endPos.X - pos.X)
				&& Math.Abs(moveVector.Y) + 0.5F >= Math.Abs(endPos.Y - pos.Y))
			{
				move(endPos.X - pos.X, endPos.Y - pos.Y);
				pos = endPos;
				setState(Unit.Idle1);
			} else {
				move(moveVector.X, moveVector.Y);

				setOrientation(moveVector);
			}
		}

		private void setOrientation(Position2D moveVector)
		{
			double direction = moveVector.getDirection();

			if (Math.PI * 15 / 8 < direction || direction < Math.PI * 1 / 8) orientation = Unit.Right;
			else if (Math.PI * 1 / 8 < direction && direction < Math.PI * 3 / 8) orientation = Unit.RightDown;
			else if (Math.PI * 3 / 8 < direction && direction < Math.PI * 5 / 8) orientation = Unit.Down;
			else if (Math.PI * 5 / 8 < direction && direction < Math.PI * 7 / 8) orientation = Unit.LeftDown;
			else if (Math.PI * 7 / 8 < direction && direction < Math.PI * 9 / 8) orientation = Unit.Left;
			else if (Math.PI * 9 / 8 < direction && direction < Math.PI * 11 / 8) orientation = Unit.LeftUp;
			else if (Math.PI * 11 / 8 < direction && direction < Math.PI * 13 / 8) orientation = Unit.Up;
			else if (Math.PI * 13 / 8 < direction && direction < Math.PI * 15 / 8) orientation = Unit.RightUp;
		}

		private void setState(String newState)
		{
			if (state != newState)
			{
				state = newState;
				stateTimeElapsed = 0;
			}
		}

	}
}
